package data.objects;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import data.meta.MetaAnnotations;
import data.meta.MetaAnnotations.MetaAssociation;
import data.meta.Meta_Association;
import data.meta.Meta_Method;
import data.meta.Meta_Parameter;
import data.meta.Meta_Property;
import data.meta.Metadata;

public class ClassSpy {
	public static Metadata getMetadata(String className) {
		 try {
			Class<?> c = Class.forName(className);
			Metadata result = new Metadata(c.getSimpleName());
			Field[] props = c.getFields();
			Method[] methods = c.getMethods();
			Boolean isAssociation = false;
			Boolean isMethod =false;
			String p="p";

			//Methoden auslesen
			for (Method method : methods) {
				isMethod = ( method.getAnnotation(data.meta.MetaAnnotations.MetaMethod.class) != null); 
				isAssociation = (method.getAnnotation(data.meta.MetaAnnotations.MetaAssociation.class) != null);
				if (isMethod){
					Meta_Method m = new Meta_Method(method.getName());
					String m_out = method.getReturnType().getName();
					if (!"void".equals(m_out)){
						m.addOutputparameter( new Meta_Parameter("return", m_out));
					}
					int i=0;
					Annotation[][] params = method.getParameterAnnotations();
					for (Class<?> types: method.getParameterTypes()) {
						if (params[i].length>0){
							MetaAnnotations.MetaParam para = (MetaAnnotations.MetaParam) params[i][0];
							p=para.value();
						}else{
							p="parameter";
						}
						m.addInputparameter(new Meta_Parameter(p, types.getName()));
						i=i+1;
					}
					result.addMethod(m);
				}else if(isAssociation){
					MetaAssociation anno = method.getAnnotation(data.meta.MetaAnnotations.MetaAssociation.class);
							Meta_Association as = new Meta_Association(anno.name(), anno.source(), anno.target());
							result.addAssociation(as);
				}
			}
			
			//Properties auslesen
			for (Field prop : props) {
				result.addProperty(new Meta_Property(prop.getName(), prop.getType().getName()));
			}
			
			
			return result;			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			return null;
		}
	}
	
  
}